#include "events.h"
#include <map>
#include<vector>
#include <memory>


namespace vortex
{
	struct RegisteredEvent
	{
		Event event;
		PFN_on_event callback;
		void* listener;
	};

	/*
	* Immediate mode event handler.
	*/
	class EventDispatcher
	{
	private:
		std::map<EventType, std::vector<RegisteredEvent>> callbacks;
	public:
		EventDispatcher() {}

		void register_event(EventType type, void* listener, PFN_on_event callback)
		{
			// do not re-register same type of events on same listener
			if (callbacks.find(type) == callbacks.end())
				callbacks.insert(std::make_pair(type, std::vector<RegisteredEvent>()));
			RegisteredEvent e;
			e.callback = callback;
			e.listener = listener;
			e.event.type = type;
			callbacks[type].push_back(e);
		}

		void fire_event(Event event, void* sender)
		{
			if (callbacks.find(event.type) == callbacks.end()) 
				return;

			for (auto& e : callbacks[event.type])
			{
				e.callback(e.event.type, sender, e.listener, event.context.data.u32);
			}
		}
	};

	static std::shared_ptr<EventDispatcher> g_event_dispatcher = nullptr;

	void register_event(EventType type, void* listener, PFN_on_event callback)
	{
		if (g_event_dispatcher == nullptr)
			g_event_dispatcher = std::make_shared<EventDispatcher>();

		g_event_dispatcher->register_event(type, listener, callback);
	}

	void fire_event(Event event, void* sender)
	{
		if (g_event_dispatcher == nullptr)
			g_event_dispatcher = std::make_shared<EventDispatcher>();
		g_event_dispatcher->fire_event(event, sender);
	}
}
